/**
 * 
 */
package org.wolf.core.schema;

import java.nio.ByteBuffer;

import org.apache.commons.codec.binary.Base64;
import org.apache.lucene.document.Field;
import org.apache.lucene.document.Fieldable;
import org.apache.lucene.search.SortField;

/**
 * @author 何小锋
 * 
 */
public class BinaryField extends FieldType {

	/**
	 * 
	 */
	private static final long serialVersionUID = 1L;

	@Override
	public SortField getSortField(DocField field, boolean reverse) {
		throw new UnsupportedOperationException(
				"can not sort on binary field: " + field.getName());
	}

	@Override
	public String toInternal(Object value) {
		if (value == null)
			return null;
		if (value instanceof byte[]) {
			return Base64.encodeBase64String((byte[]) value);
		} else if (value instanceof ByteBuffer
				&& ((ByteBuffer) value).hasArray()) {
			ByteBuffer byteBuf = (ByteBuffer) value;
			byte[] buf = byteBuf.array();
			int offset = byteBuf.position();
			int len = byteBuf.limit() - byteBuf.position();
			if (offset > 0 && len > 0) {
				byte[] target = new byte[len];
				System.arraycopy(buf, offset, target, 0, len);
				return Base64.encodeBase64String(target);
			}
			return Base64.encodeBase64String(buf);
		} else
			return value.toString();
	}

	@Override
	public Object toExternal(Fieldable f) {
		return ByteBuffer.wrap(f.getBinaryValue(), f.getBinaryOffset(),
				f.getBinaryLength());
	}

	@Override
	public Field createField(DocField field, Object value, float boost) {
		if (value == null || !field.isStored())
			return null;
		byte[] buf = null;
		int offset = 0, len = 0;
		if (value instanceof byte[]) {
			buf = (byte[]) value;
			len = buf.length;
		} else if (value instanceof ByteBuffer
				&& ((ByteBuffer) value).hasArray()) {
			ByteBuffer byteBuf = (ByteBuffer) value;
			buf = byteBuf.array();
			offset = byteBuf.position();
			len = byteBuf.limit() - byteBuf.position();
		} else {
			String strVal = value.toString();
			buf = Base64.decodeBase64(strVal);
			offset = 0;
			len = buf.length;
		}
		Field f = new Field(field.getName(), buf, offset, len);
		f.setBoost(boost);
		return f;
	}

}
